import java.util.Scanner;
import java.util.LinkedList;
import java.io.*;
import java.nio.file.Paths;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.io.IOException;

public class CinemaSystem {
    Administrator administrator = new Administrator();//管理者
    Manager manager = new Manager();//经理
    FrontDeskReception frontDeskReception = new FrontDeskReception();//前台

    //使用LinkedList
    private LinkedList<Administrator> adminList = new LinkedList<Administrator>();  // 管理员链表
    private LinkedList<Manager> managerList = new LinkedList<Manager>(); // 经理链表
    private LinkedList<FrontDeskReception> frontDeskReceptionList = new LinkedList<FrontDeskReception>(); // 前台链表

    // 初始化管理员admin信息
    //Administrator admin = new Administrator("110101","admin","yuninfo#777","2025-01-01 00:00:00","超级管理员","13102410251");

    // 添加用户数据文件路径
    private static final String USER_DATA_FILE = "user_data.ser";
    private Users currentUser = null; // 当前登录用户
    //添加单例模式，保证只有一个CinemaSystem实例，确保所有操作都针对同一个数据源（若不使用这个，就将adminList作为参数传递给changePassword方法中）
    private static CinemaSystem instance;
    public static CinemaSystem getInstance() {
        if (instance == null) {
            instance = new CinemaSystem();
        }
        return instance;
    }

    //获取管理员链表
    public LinkedList<Administrator> getAdminList() {
        return adminList;
    }
    //获取经理列表
    public LinkedList<Manager> getManagerList() {
        return managerList;
    }
    //获取前台列表
    public LinkedList<FrontDeskReception> getFrontDeskReceptionList() {
        return frontDeskReceptionList;
    }

    /*
    public CinemaSystem() {
        // 初始化时将admin添加到管理员链表
        adminList.add(admin);
    }
     */

    private CinemaSystem() {
        // 初始化用户列表
        adminList = new LinkedList<>();
        managerList = new LinkedList<>();
        frontDeskReceptionList = new LinkedList<>();
        // 尝试从文件加载用户数据
        if (!loadUserData()) {
            // 加载失败时初始化默认管理员
            // 创建管理员对象并赋值给变量
            Administrator defaultAdmin = new Administrator("110101", "admin", "yuninfo#777", new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date()), "超级管理员", "13102410251");
            adminList.add(defaultAdmin);
            saveUserData(); // 保存初始数据
        }else {
            // 检查并修正超级管理员密码
            for (Administrator admin : adminList) {
                if ("admin".equals(admin.getName()) && !"yuninfo#777".equals(admin.getPassword())) {
                    admin.setPassword("yuninfo#777");
                    saveUserData(); // 保存修正后的密码
                    System.out.println("超级管理员密码已重置为默认值");
                }
            }
        }
    }


    // 保存用户数据到文件
    public boolean saveUserData() {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(USER_DATA_FILE))) {
            oos.writeObject(adminList);
            oos.writeObject(managerList);
            oos.writeObject(frontDeskReceptionList);
            return true;
        } catch (IOException e) {
            System.err.println("保存用户数据失败: " + e.getMessage());
            return false;
        }
    }

    // 从文件加载用户数据
    @SuppressWarnings("unchecked")
    private boolean loadUserData() {
        File file = new File(USER_DATA_FILE);
        if (!file.exists()) return false;

        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
            adminList = (LinkedList<Administrator>) ois.readObject();
            managerList = (LinkedList<Manager>) ois.readObject();
            frontDeskReceptionList = (LinkedList<FrontDeskReception>) ois.readObject();
            return true;
        } catch (IOException | ClassNotFoundException e) {
            System.err.println("加载用户数据失败: " + e.getMessage());
            return false;
        }
    }

    public void setCurrentUser(Users user) {
        this.currentUser = user;
    }

    public Users getCurrentUser() {
        return currentUser;
    }


    public void showMenu() {
        Scanner scanner = new Scanner(System.in);
        System.out.println("\n========== 影院管理系统 ==========");
        System.out.println("1. 登录");
        System.out.println("0. 退出系统");
        System.out.print("请选择操作：");
        int choice = scanner.nextInt();//不具有容错功能，输入非整数会出现异常，终止运行。
        while (true) {
            switch (choice) {
                case 1:
                    System.out.println("请选择用户类型：");
                    System.out.println("1-管理员 2-经理 3-前台");
                    int userType = scanner.nextInt();
                    switch (userType) {
                        case 1:
                            //管理员登录
                            System.out.println("请输入用户名：");
                            String adminUsername = scanner.next(); // 获取用户输入的用户名
                            System.out.println("请输入密码：");
                            String adminPassword = scanner.next(); // 获取用户输入的密码
                            // 验证登录凭据
                            boolean loginSuccess = false;
                            Administrator loggedInAdmin = null;
                            for (Administrator admin : adminList) {
                                if (admin.getName().equals(adminUsername) && admin.getPassword().equals(adminPassword)) {
                                    loginSuccess = true;
                                    loggedInAdmin = admin;
                                    break;
                                }
                            }

                            if (loginSuccess) {
                                setCurrentUser(loggedInAdmin);//登录成功后设置当前用户
                                System.out.println("登录成功！");
                                //管理员操作
                                while (choice != 0) {
                                    System.out.println("\n========== 管理员操作 ==========");
                                    System.out.println("1.修改管理员密码");
                                    System.out.println("2.重置经理或前台密码");
                                    System.out.println("3.列出所有管理员的信息");
                                    System.out.println("4.列出所有经理的信息");
                                    System.out.println("5.列出所有前台的信息");
                                    System.out.println("6.删除管理员/经理/前台的信息");
                                    System.out.println("7.查询管理员/经理/前台的信息");
                                    System.out.println("8.增加管理员/经理/前台的信息");
                                    System.out.println("9.修改经理/前台的信息（用户类型和用户手机号）");
                                    System.out.println("0.退出登录");
                                    System.out.println("==============================");
                                    System.out.print("请选择操作：");
                                    choice = scanner.nextInt();
                                    switch (choice) {
                                        case 1:
                                            //修改管理员密码
                                            System.out.println("请输入新密码：");
                                            loggedInAdmin.changePassword(scanner.next());
                                            break;

                                        case 2:
                                            //重置经理或前台密码
                                            administrator.resetPassword();
                                            break;
                                        case 3:
                                            //列出所有管理员的信息
                                            administrator.listAllUsers();
                                            break;
                                        case 4:
                                            //列出所有经理的信息
                                            manager.listAllUsers();
                                            break;
                                        case 5:
                                            //列出所有前台的信息
                                            frontDeskReception.listAllUsers();
                                            break;
                                        case 6:
                                            //删除管理员/经理/前台的信息
                                            administrator.deleteUser();
                                            break;
                                        case 7:
                                            //查询管理员/经理/前台的信息
                                            administrator.searchUser();
                                            break;
                                        case 8:
                                            //增加管理员/经理/前台的信息
                                            administrator.addUser();
                                            break;
                                        case 9:
                                            //修改经理/前台的信息（用户类型和用户手机号）
                                            administrator.modifyUser();
                                            break;
                                        case 0:
                                            System.out.println("退出登录！");
                                            showMenu();
                                            //administrator.clearLogFile();
                                            break;
                                        default:
                                            System.out.println("无效选择，请重新输入！");
                                    }
                                }
                            } else {
                                System.out.println("管理员登录失败！");
                                break;
                            }

                        case 2:
                            //经理登录
                            System.out.println("\n========== 影院管理系统 ==========");
                            System.out.println("请输入用户名：");
                            System.out.println("请输入密码：");
                            if (manager.logIn(scanner.next(), scanner.next())) {
                                System.out.println("登录成功！");
                                boolean managerLoggedIn = true;
                                //经理操作
                                while (managerLoggedIn) {
                                    System.out.println("\n========== 经理操作 ==========");
                                    System.out.println("1.修改经理密码");
                                    System.out.println("2.重置前台密码");
                                    System.out.println("3.影片管理功能");
                                    System.out.println("4.排片管理功能");
                                    System.out.println("5.查看销售数据");
                                    System.out.println("0.退出登录");
                                    System.out.println("==============================");
                                    System.out.print("请选择操作：");
                                    choice = scanner.nextInt();
                                    switch (choice) {
                                        case 1:
                                            //修改经理密码
                                            System.out.println("请输入新密码：");
                                            manager.changePassword(scanner.next());
                                            break;
                                        case 2:
                                            //重置前台密码
                                            administrator.resetPassword();
                                            break;
                                        case 3:
                                            //影片管理功能
                                            Movies movies = new Movies();
                                            while (true) {
                                                System.out.println("\n========== 影片管理功能 ==========");
                                                System.out.println("1. 列出所有影片");
                                                System.out.println("2. 添加影片");
                                                System.out.println("3. 修改影片");
                                                System.out.println("4. 删除影片");
                                                System.out.println("5. 查询影片");
                                                System.out.println("0. 返回上级菜单");
                                                System.out.println("============================\n");
                                                System.out.print("请选择操作：");
                                                int movieChoice = scanner.nextInt();
                                                scanner.nextLine(); // 消耗换行符

                                                switch (movieChoice) {
                                                    case 1:
                                                        movies.listAllMovies();
                                                        break;
                                                    case 2:
                                                        movies.addMovie();
                                                        break;
                                                    case 3:
                                                        movies.modifyMovie();
                                                        break;
                                                    case 4:
                                                        movies.deleteMovie();
                                                        break;
                                                    case 5:
                                                        movies.searchMovie();
                                                        break;
                                                    case 0:
                                                        System.out.println("返回上级菜单");
                                                        break;
                                                    default:
                                                        System.out.println("无效选择，请重新输入！");
                                                }
                                                if (movieChoice == 0) break;
                                            }
                                            break;
                                        case 4:
                                            // 场次管理功能
                                            Session sessionManager = new Session();
                                            while (true) {
                                                System.out.println("\n========== 场次管理功能 ==========");
                                                System.out.println("1. 查看所有场次信息");
                                                System.out.println("2. 添加场次");
                                                System.out.println("3. 修改场次");
                                                System.out.println("4. 删除场次");
                                                System.out.println("5. 查询场次");
                                                System.out.println("6. 自动排片");
                                                System.out.println("0. 返回上级菜单");
                                                System.out.println("============================\n");
                                                System.out.print("请选择操作：");


                                                int sessionChoice = scanner.nextInt();
                                                scanner.nextLine(); // 消耗换行符

                                                switch (sessionChoice) {
                                                    case 1:
                                                        sessionManager.listAllSessions();
                                                        break;
                                                    case 2:
                                                        sessionManager.addSession();
                                                        break;
                                                    case 3:
                                                        sessionManager.modifySession();
                                                        break;
                                                    case 4:
                                                        sessionManager.deleteSession();
                                                        break;
                                                    case 5:
                                                        System.out.println("请输入要查询的影片名称：");
                                                        String movieName = scanner.nextLine();
                                                        // 实现查询特定影片场次的功能
                                                        LinkedList<Session> sessions = sessionManager.getSessionList();
                                                        for (Session s : sessions) {
                                                            if (s.getMovieName().equals(movieName)) {
                                                                System.out.println(s.getMovieName() + " " + s.getStartTime() + " " + s.getHallName());
                                                            }
                                                        }
                                                        break;
                                                    case 6:
                                                        // 自动排片功能
                                                        System.out.println("1. 为所有未排片电影自动排片");
                                                        System.out.println("2. 指定电影自动排片");
                                                        System.out.print("请选择自动排片方式：");
                                                        int scheduleChoice = scanner.nextInt();
                                                        scanner.nextLine();

                                                        Session autoScheduler = new Session();
                                                        if (scheduleChoice == 1) {
                                                            autoScheduler.autoSchedule();
                                                        } else {
                                                            System.out.println("请输入电影名称：");
                                                            String targetMovieName = scanner.nextLine();
                                                            autoScheduler.autoSchedule(targetMovieName);
                                                        }
                                                        break;
                                                    case 0:
                                                        System.out.println("返回上级菜单");
                                                        break;
                                                    default:
                                                        System.out.println("无效选择，请重新输入！");
                                                }
                                                if (sessionChoice == 0) break;
                                            }
                                            break;
                                        case 5:
                                            // 查看销售数据
                                            Sales sales = new Sales();
                                            while (true) {
                                                System.out.println("\n========== 销售数据查看 ==========");
                                                System.out.println("1. 查看当日销售数据");
                                                System.out.println("2. 查看当周销售数据");
                                                System.out.println("3. 查看当月销售数据");
                                                System.out.println("0. 返回上级菜单");
                                                System.out.println("============================\n");
                                                System.out.print("请选择操作：");
                                                int salesChoice = scanner.nextInt();
                                                scanner.nextLine(); // 消耗换行符
                                                switch (salesChoice) {
                                                    case 1:
                                                        System.out.println("\n=== 当日销售数据 ===");
                                                        sales.showDailySales();
                                                        break;
                                                    case 2:
                                                        System.out.println("\n=== 当周销售数据 ===");
                                                        sales.showWeeklySales();
                                                        break;
                                                    case 3:
                                                        System.out.println("\n=== 当月销售数据 ===");
                                                        sales.showMonthlySales();
                                                        break;
                                                    case 0:
                                                        System.out.println("返回上级菜单");
                                                        break;
                                                    default:
                                                        System.out.println("无效选择，请重新输入！");
                                                }
                                                if (salesChoice == 0) break;
                                            }
                                            break;
                                        case 0:
                                            System.out.println("退出登录！");
                                            managerLoggedIn = false;
                                            showMenu();
                                            break;
                                    }
                                }
                            } else {
                                System.out.println("经理登录失败！");
                                break;
                            }

                        case 3:
                            //前台登录
                            System.out.println("\n========== 影院管理系统 ==========");
                            System.out.println("请输入用户名：");
                            String fdUsername = scanner.next(); // 获取用户输入的用户名
                            System.out.println("请输入密码：");
                            String fdPassword = scanner.next(); // 获取用户输入的密码
                            if (frontDeskReception.logIn(fdUsername, fdPassword)) {
                                System.out.println("登录成功！");
                                //前台操作
                                while (true) {
                                    System.out.println("\n========== 前台操作 ==========");
                                    System.out.println("1.列出所有正在上映的影片信息");
                                    System.out.println("2.列出所有场次的信息");
                                    System.out.println("3.列出指定电影和场次的信息");
                                    System.out.println("4.售票功能");
                                    System.out.println("0.退出登录");
                                    System.out.println("============================\n");
                                    System.out.print("请选择操作：");
                                    int fdChoice = scanner.nextInt();
                                    scanner.nextLine(); // 消耗换行符

                                    switch (fdChoice) {
                                        case 1:
                                            // 列出所有正在上映的影片信息
                                            Movies movies = new Movies();
                                            movies.listAllMovies();
                                            break;
                                        case 2:
                                            // 列出所有场次的信息
                                            Session session = new Session();
                                            session.listAllSessions();
                                            break;
                                        case 3:
                                            // 列出指定电影和场次的信息
                                            System.out.println("请输入要查询的影片名称：");
                                            String movieName = scanner.nextLine();
                                            FrontDeskReception.listMovieSessionsWithSeats(movieName);
                                            break;
                                        case 4:
                                            // 售票功能
                                            TicketSellingFunction ticketSystem = new TicketSellingFunction();
                                            //先展示以下相关票价政策
                                            System.out.println("========== 相关票价政策 ==========");
                                            System.out.println("1. 儿童票六折");
                                            System.out.println("2. 普通票全价");
                                            System.out.println("每个电影票价以场次从早到晚的顺序依次按一定比例递增");
                                            System.out.println("============================\n");

                                            ticketSystem.sellTicketProcess();
                                            break;
                                        case 0:
                                            System.out.println("退出登录");
                                            showMenu();
                                            break;
                                        default:
                                            System.out.println("无效选择，请重新输入！");
                                            break;
                                    }
                                }
                            } else {
                                System.out.println("前台登录失败！");
                                break;
                            }
                    }
                case 0:
                    //清空日志文件
                    administrator.clearLogFile();
                    Session.clearLogFile();
                    //CinemaSystem.getInstance().clearAllLogFiles();
                    System.out.println("退出登录！");
                    System.exit(0);
                    break;
                default:
                    System.out.println("无效选择，请重新输入！");
            }
        }
    }
}






